﻿using FreeSql;
using KrasDD.Dtos;
using KrasDD.Extensions;
using KrasDD.Models;
using KrasDD.Utils;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Data.SqlClient;
using System.Data;
using System.Data.Common;

namespace KrasDD.Controllers
{
    /// <summary>
    /// 与数据库直接进行交互的控制器
    /// </summary>
    /// <param name="fsql"></param>
    [ApiController]
    [Route("[controller]/[action]")]
    public class PomController(IFreeSql fsql, IDistributedCache cache) : ControllerBase
    {

        [HttpGet]
        public IResult CompileDirectoryToDll()
        {
            return Results.Ok(CsCompiler.CompileDirectoryToDll("DyModels", @"E:\Desktop\新建文件夹 (7)\KrasDD\bin\Debug\net9.0\outputdll\dymodels.dll"));
        }


        [HttpGet]
        public IResult LoadDLl()
        {

            var method = AppContainer.Ifsq.Select<METHOD>().Where(l => l.ID == "40DF03E8ADFD4AAD86010177174BE1F0").First();

            AppContainer.CallMethod(method, "123");

            return Results.Ok("加载成功");
        }

        //[HttpGet]
        //public IResult CompileDirectoryToDll()
        //{
        //    return Results.Ok(CsCompiler.CompileDirectoryToDll("DyModels", "dymodels.dll"));
        //}







        /// <summary>
        /// 新增数据
        /// </summary>
        /// <param name="type"></param>
        /// <param name="obj"></param>
        /// <returns></returns>
        [HttpPost]
        public IResult Add(CrudRequest crudData)
        {
            var results = new List<Dictionary<string, object>>();
            var type = crudData.type;
            string id = crudData.id ?? throw new ArgumentException("");
            var tableName = DBHelper.GetTableName(type, out var dbTableInfo);



            var data = crudData.data;


            // 2. 将obj转换为目标实体类型
            var json = JSON.Serialize(data);


            if (data != null && !string.IsNullOrEmpty(id))
            {
                // 使用更安全的字典键检查方式
                var key = data.Keys.FirstOrDefault(k =>
                    string.Equals(k, "id", StringComparison.OrdinalIgnoreCase));
                if (key == null)
                {
                    data["id"] = id;
                }
                else if (!string.Equals(data[key].ToString(), id, StringComparison.OrdinalIgnoreCase))
                {
                    data[key] = id;
                }
            }
            // 3. 使用fsql添加数据
            var insert = fsql.InsertDict(data).AsTable(tableName);
            var rows = insert.ExecuteInserted();
            results.AddRange(rows);

            // 3. 使用fsql添加数据

            return Results.Ok(results);
        }
        /// <summary>
        /// 修改数据
        /// </summary>
        /// <param name="type"></param>
        /// <param name="obj"></param>
        /// <returns></returns>
        [HttpPost]
        public ApiResponse<List<Dictionary<string, object>>> Update(CrudRequest crudData)
        {
            var results = new List<Dictionary<string, object>>();
            var type = crudData.type;
            string id = crudData.id ?? throw new ArgumentException("");
            var tableName = DBHelper.GetTableName(type, out var dbTableInfo);

            var data = crudData.data;

            if (data != null && !string.IsNullOrEmpty(id))
            {
                // 使用更安全的字典键检查方式
                var key = data.Keys.FirstOrDefault(k =>
                    string.Equals(k, "id", StringComparison.OrdinalIgnoreCase));
                if (key == null)
                {
                    data["id"] = id;
                }
                else if (!string.Equals(data[key].ToString(), id, StringComparison.OrdinalIgnoreCase))
                {
                    data[key] = id;
                }
            }
            // 3. 使用fsql添加数据
            var insert = fsql.UpdateDict(data).AsTable(tableName);
            var rows = insert.ExecuteUpdated();
            results.AddRange(rows);

            // 3. 使用fsql添加数据

            return ApiResponse<List<Dictionary<string, object>>>.Ok(results);
        }

        [HttpPost]
        public ApiResponse<List<Dictionary<string, object>>> Delete(CrudRequest crudData)
        {
            var results = new List<Dictionary<string, object>>();
            var type = crudData.type;
            string id = crudData.id ?? throw new ArgumentException("");
            var tableName = DBHelper.GetTableName(type, out var dbTableInfo);
            var data = crudData.data;

            // 1. 通过类型名获取实体Type 
            var entityType = AppDomain.CurrentDomain
                .GetAssemblies()
                .SelectMany(a => a.GetTypes())
                .FirstOrDefault(t => t.Name.Equals(type, StringComparison.OrdinalIgnoreCase));
            if (entityType == null)
                return ApiResponse<List<Dictionary<string, object>>>.Fail($"未找到类型: {type}");
            if (data != null && !string.IsNullOrEmpty(id))
            {
                // 使用更安全的字典键检查方式
                var key = data.Keys.FirstOrDefault(k =>
                    string.Equals(k, "id", StringComparison.OrdinalIgnoreCase));
                if (key == null)
                {
                    data["id"] = id;
                }
                else if (!string.Equals(data[key].ToString(), id, StringComparison.OrdinalIgnoreCase))
                {
                    data[key] = id;
                }
            }
            // 3. 使用fsql添加数据
            var insert = fsql.DeleteDict(data).AsTable(tableName);
            var rows = insert.ExecuteDeleted();
            results.AddRange(rows);

            // 3. 使用fsql添加数据
            return ApiResponse<List<Dictionary<string, object>>>.Ok(results);
        }


        [HttpPost]
        public ApiResponse<List<Dictionary<string, object>>> Cud(List<CrudRequest> crudDatas)
        {

            var results = new List<Dictionary<string, object>>();

            using (var uow = fsql.CreateUnitOfWork())
            {
                foreach (var crudData in crudDatas)
                {
                    var type = crudData.type;
                    string id = crudData.id ?? throw new ArgumentException("");

                    var tableName = DBHelper.GetTableName(type, out var dbTableInfo);

                    var action = crudData.action;
                    var data = crudData.data;

                    var dictRest = new List<Dictionary<string, object>>();
                    var key = data.Keys.FirstOrDefault(k =>
                       string.Equals(k, "id", StringComparison.OrdinalIgnoreCase));
                    if (action == CrudActionEnum.Add)
                    {

                        if (string.IsNullOrEmpty(key))
                        {
                            data.Add("id", id);
                        }
                        else
                        {
                            data[key] = id;
                        }
                        var insert = uow.Orm.InsertDict(data).AsTable(tableName);
                        dictRest.AddRange(insert.ExecuteInserted());
                    }


                    if (action == CrudActionEnum.Update)
                    {

                        //不允许修改ID
                        if (!string.IsNullOrEmpty(key))
                        {
                            data.Remove(key);
                        }

                        var insert = uow.Orm.UpdateDict(data).AsTable(tableName).WherePrimary(id);
                        dictRest.AddRange(insert.ExecuteUpdated());
                    }

                    if (action == CrudActionEnum.Delete)
                    {
                        //仅支持通过ID删除
                        data = new Dictionary<string, object>();
                        data.Add("id", id);
                        var insert = uow.Orm.DeleteDict(data).AsTable(tableName);
                        dictRest.AddRange(insert.ExecuteDeleted());
                    }
                    results.AddRange(dictRest);
                }
                uow.Commit();
            }

            return ApiResponse<List<Dictionary<string, object>>>.Ok(results);
        }

        [HttpGet]
        public ApiResponse<List<CrudResonse>> FindById(string type, string id)
        {
            var tableName = DBHelper.GetTableName(type, out var dbTableInfo);
            var sql = $"select * from  {tableName} where  id = @id ";
            var pams = new SqlParameter[] { new SqlParameter("@id", id) };
            var results = new List<CrudResonse>();
            // 1. 基本用法
            fsql.Ado.ExecuteReader((FreeSql.Internal.Model.FetchCallbackArgs<DbDataReader> reader) =>
            {
                DbDataReader? dataReader = reader.Object;

                var obj = dataReader.GetDictionary();

                results.Add(new CrudResonse() { id = id, type = type, data = obj });
            }, CommandType.Text, sql, pams);
            return ApiResponse<List<CrudResonse>>.Ok(results);
        }


        [HttpPost]
        public ApiResponse<List<CrudResonse>> FindByCondition(QueryWrapper queryWrapper)
        {

            var results = new List<CrudResonse>();
            var dict = new Dictionary<string, object>();
            var sql = queryWrapper.build(dict);
            var pams = dict.Select(l => new SqlParameter(l.Key, l.Value)).ToArray();
            // 1. 基本用法
            fsql.Ado.ExecuteReader((reader) =>
            {
                var dataReader = reader.Object;
                var obj = dataReader.GetDictionary();
                results.Add(new CrudResonse() { id = obj["id"]?.ToString(), type = queryWrapper.type, data = obj });
            }, CommandType.Text, sql, pams);
            return ApiResponse<List<CrudResonse>>.Ok(results);
        }


    }
}
